package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.*;
import com.zb.mapper.ZjNetworkEmpFieldMapper;
import com.zb.result.PageUtil;
import com.zb.service.ZjNetworkEmpFieldContentService;
import com.zb.service.ZjNetworkEmpFieldService;
import com.zb.service.ZjNetworkEmpFieldValService;
import com.zb.vo.NetworkFieldListVo;
import com.zb.vo.NetworkFieldSelectVo;
import com.zb.vo.NetworkFieldVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 网点人员字段表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-10-18
 */
@Service
public class ZjNetworkEmpFieldServiceImpl extends ServiceImpl<ZjNetworkEmpFieldMapper, ZjNetworkEmpField> implements ZjNetworkEmpFieldService {
    @Resource
    private ZjNetworkEmpFieldMapper networkEmpFieldMapper;
    @Resource
    private ZjNetworkEmpFieldContentService networkEmpFieldContentService;
    @Resource
    private ZjNetworkEmpFieldValService networkEmpFieldValService;

    // 新增或修改服务商人员自定义字段
    @Override
    @Transactional
    public void save(Long custAccId, NetworkFieldVo networkFieldVo) {
        Assert.isTrue(null == networkEmpFieldMapper.existByName(custAccId, networkFieldVo.getId(), networkFieldVo.getName()), "字段名称已重复");
        ZjNetworkEmpField field = new ZjNetworkEmpField();
        BeanUtil.copyProperties(networkFieldVo, field);
        field.setDisabled(networkFieldVo.getStatus());
        if (null != field.getId()) {
            this.updateById(field);
        } else {
            field.setId(IdWorker.getId());
            field.setCustAccId(custAccId);
            field.setListSelect(null != field.getListSelect() && field.getListSelect());
            field.setListShow(null != field.getListShow() && field.getListShow());
            this.save(field);
        }
        networkEmpFieldContentService.save(custAccId, field.getId(), networkFieldVo.getContents(), networkFieldVo.getDelContentIds());
    }

    // 获取服务商人员字段列表
    @Override
    public Map<String, Object> getList(Long custAccId, SelectVo selectVo) {
        PageUtil.setPageLimit(selectVo);
        QueryWrapper<ZjNetworkEmpField> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_update");
        wrapper.in("cust_acc_id", custAccId);
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("name", selectVo.getName());
        }
        Page<ZjNetworkEmpField> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);
        List<ZjNetworkEmpFieldContent> contentList = networkEmpFieldContentService.getByNetworkFieldEmpIds(page.getRecords().stream().map(ZjNetworkEmpField::getId).toList());

        List<NetworkFieldListVo> voList = page.getRecords().stream().map(field -> {
            NetworkFieldListVo vo = new NetworkFieldListVo();
            BeanUtil.copyProperties(field, vo);
            vo.setStatus(field.getDisabled());
            vo.setCreateTime(field.getGmtCreate());
            vo.setUpdateTime(field.getGmtUpdate());
            vo.setContent(contentList.stream().filter(f -> Objects.equals(f.getNetworkFieldEmpId(), field.getId())).map(ZjNetworkEmpFieldContent::getVal).collect(Collectors.joining("、")));
            return vo;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }

    // 获取服务商人员字段详情
    @Override
    public NetworkFieldVo getDetail(Long id) {
        ZjNetworkEmpField field = this.getById(id);
        Assert.isTrue(null != field, "服务商人员字段ID参数["+ id +"]的数据不存在");
        NetworkFieldVo vo = new NetworkFieldVo();
        BeanUtil.copyProperties(field, vo);
        vo.setStatus(field.getDisabled());
        vo.setContents(networkEmpFieldContentService.getByNetworkFieldEmpId(id).stream().map(cont -> {
            FieldContentVo contentVo = new FieldContentVo();
            contentVo.setId(cont.getId());
            contentVo.setVal(cont.getVal());
            return contentVo;
        }).toList());
        return vo;
    }

    // 批量启用或禁用服务商人员字段
    @Override
    public void updateDisableBatchById(List<Long> ids, boolean status) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        networkEmpFieldMapper.updateDisableBatchById(ids, status);
    }

    // 批量更改移动端隐藏或显示服务商人员字段
    @Override
    public void updateMobileShowBatchById(List<Long> ids, boolean mobileShow) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        networkEmpFieldMapper.updateMobileShowBatchById(ids, mobileShow);
    }

    // 批量删除服务商人员字段
    @Override
    public void deleteBatchById(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        // 查询服务商人员是否关联字段
        List<Long> ids2 =  networkEmpFieldValService.getRelationByNetworkEmpFieldId(ids);
        if (CollectionUtil.isNotEmpty(ids2)) {
            QueryWrapper<ZjNetworkEmpField> wrapper = new QueryWrapper<>();
            wrapper.select("name");
            wrapper.in("id", ids2.stream().distinct().toList());
            Assert.isTrue(false, "服务商人员字段["+ this.list(wrapper).stream().map(ZjNetworkEmpField::getName).collect(Collectors.joining("、"))+"]已被关联使用中，不可删除");
        }
        networkEmpFieldContentService.deleteBatchByNetworkEmpFieldIds(ids);
        this.removeByIds(ids);
    }

    // 获取服务商人员字段下拉数据
    @Override
    public Map<String, Object> getNetworkEmpCustomFields(Long custAccId, boolean mobileSelect) {
        QueryWrapper<ZjNetworkEmpField> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_update");
        wrapper.select("id", "name", "type", "upload_size", "upload_qty", "tip", "is_required AS required");
        wrapper.eq("cust_acc_id", custAccId).eq("is_disabled", false);
        if (mobileSelect) {
            wrapper.eq("is_mobile_show", true);
        }
        List<ZjNetworkEmpField> fieldList = this.list(wrapper);
        List<ZjNetworkEmpFieldContent> contents = networkEmpFieldContentService.getByNetworkFieldEmpIds(fieldList.stream().map(ZjNetworkEmpField::getId).toList());

        return PageUtil.rows(fieldList.stream().map(field -> {
            NetworkFieldSelectVo vo = new NetworkFieldSelectVo();
            BeanUtil.copyProperties(field, vo);
            vo.setContents(contents.stream().filter(f -> Objects.equals(f.getNetworkFieldEmpId(), field.getId())).map(cont -> {
                FieldContentVo contentVo = new FieldContentVo();
                contentVo.setId(cont.getId());
                contentVo.setVal(cont.getVal());
                return contentVo;
            }).toList());
            return vo;
        }).toList());
    }
}
